package ast

type List interface {
	Pos() int
	End() int
	NodeAt(index int) Node
	Len() int
}

type NodeList struct {
	nodes []Node
	textRange
}

func (nl *NodeList) Add(node Node) { nl.nodes = append(nl.nodes, node) }
func (nl *NodeList) At(index int) Node { return nl.nodes[index] }
func (nl *NodeList) NodeAt(index int) Node { return nl.nodes[index] }
func (nl *NodeList) NodeIndex(node Node) int {
	for i, t := range nl.nodes {
		if t == node {
			return i
		}
	}
	return -1
}
func (nl *NodeList) Len() int {
	if nl == nil {
		return 0
	}
	return len(nl.nodes)
}
func (nl *NodeList) Array() []Node {
	if nl != nil {
		return nl.nodes
	}
	return nil
}

type DeclarationList struct {
	declarations []Declaration
	textRange
}

func (dl *DeclarationList) Add(node Declaration)     { dl.declarations = append(dl.declarations, node) }
func (dl *DeclarationList) At(index int) Declaration { return dl.declarations[index] }
func (dl *DeclarationList) NodeAt(index int) Node    { return dl.declarations[index] }
func (dl *DeclarationList) Len() int                 {
	if dl == nil {
		return 0
	}
	return len(dl.declarations)
}
func (dl *DeclarationList) Index(node Declaration) int {
	for i, d := range dl.declarations {
		if d == node {
			return i
		}
	}
	return -1
}
func (dl *DeclarationList) Array() []Declaration {
	if dl != nil {
		return dl.declarations
	}
	return nil
}

type ExpressionList struct {
	expressions []Expression
	textRange
}

func (el *ExpressionList) Add(node Expression)     { el.expressions = append(el.expressions, node) }
func (el *ExpressionList) At(index int) Expression { return el.expressions[index] }
func (el *ExpressionList) NodeAt(index int) Node   { return el.expressions[index] }
func (el *ExpressionList) Len() int                {
	if el == nil {
		return 0
	}
	return len(el.expressions)
}
func (el *ExpressionList) Index(node Expression) int {
	for i, d := range el.expressions {
		if d == node {
			return i
		}
	}
	return -1
}
func (el *ExpressionList) Array() []Expression {
	if el != nil {
		return el.expressions
	}
	return nil
}

type StatementList struct {
	statements []Statement
	textRange
}

func (sl *StatementList) Add(node Statement)     { sl.statements = append(sl.statements, node) }
func (sl *StatementList) At(index int) Statement { return sl.statements[index] }
func (sl *StatementList) NodeAt(index int) Node  { return sl.statements[index] }
func (sl *StatementList) NodeIndex(node Node) int {
	for i, t := range sl.statements {
		if t == node {
			return i
		}
	}
	return -1
}
func (sl *StatementList) Len() int              {
	if sl == nil {
		return 0
	}
	return len(sl.statements)
}
func (sl *StatementList) Index(node Statement) int {
	for i, d := range sl.statements {
		if d == node {
			return i
		}
	}
	return -1
}
func (sl *StatementList) Array() []Statement {
	if sl != nil {
		return sl.statements
	}
	return nil
}

type TypeList struct {
	types []Type
	textRange
}

func (tl *TypeList) Add(node Type) { tl.types = append(tl.types, node) }
func (tl *TypeList) At(index int) Type { return tl.types[index] }
func (tl *TypeList) NodeAt(index int) Node { return tl.types[index] }
func (tl *TypeList) NodeIndex(node Node) int {
	for i, t := range tl.types {
		if t == node {
			return i
		}
	}
	return -1
}
func (tl *TypeList) Len() int {
	if tl == nil {
		return 0
	}
	return len(tl.types)
}
func (tl *TypeList) Index(node Type) int {
	for i, d := range tl.types {
		if d == node {
			return i
		}
	}
	return -1
}
func (tl *TypeList) Array() []Type {
	if tl != nil {
		return tl.types
	}
	return nil
}


type DocumentList struct {
	documents []Document
	textRange
}

func (dl *DocumentList) Add(node Document) { dl.documents = append(dl.documents, node) }
func (dl *DocumentList) At(index int) Document { return dl.documents[index] }
func (dl *DocumentList) NodeAt(index int) Node { return dl.documents[index] }
func (dl *DocumentList) NodeIndex(node Node) int {
	for i, t := range dl.documents {
		if t == node {
			return i
		}
	}
	return -1
}
func (dl *DocumentList) Len() int {
	if dl == nil {
		return 0
	}
	return len(dl.documents)
}
func (dl *DocumentList) Index(node Document) int {
	for i, d := range dl.documents {
		if d == node {
			return i
		}
	}
	return -1
}
func (dl *DocumentList) Array() []Document {
	if dl != nil {
		return dl.documents
	}
	return nil
}